using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Web;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;

namespace c3o.Framework.Web
{
    public class uTorrentData
    {
        public static void StopDownload(string webUiUrl, string webUiLogin, string webUiPassword, string key)
        {
            webUiUrl = String.Format("{0}?action=stop&hash={1}", webUiUrl, key);

            // Read Data from uTorrent
            string JsonData = Call(webUiUrl, webUiLogin, webUiPassword);
        }

        public static void StartDownload(string webUiUrl, string webUiLogin, string webUiPassword, string key)
        {
            webUiUrl = String.Format("{0}?action=start&hash={1}", webUiUrl, key);

            // Read Data from uTorrent
            string JsonData = Call(webUiUrl, webUiLogin, webUiPassword);
        }


        public static void RemoveDownload(string webUiUrl, string webUiLogin, string webUiPassword, string key)
        {
            webUiUrl = String.Format("{0}?action=remove&hash={1}", webUiUrl, key);

            // Read Data from uTorrent
            string JsonData = Call(webUiUrl, webUiLogin, webUiPassword);
        }        
        
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="url">URL of uTorrent Web UI EX: http://140.188.204.53:8080/gui/</param>
        /// <returns></returns>
        public static DataTable TorrentList(string webUiUrl, string webUiLogin, string webUiPassword)
        {
            DataTable dt = null;

            webUiUrl += @"?list=1";

            // Read Data from uTorrent
            string JsonData = Call(webUiUrl, webUiLogin, webUiPassword);

            if (JsonData != null)
            {
                // Clean up string
                JsonData = JsonData.Replace("'", "");     // Remove Any single quotes
                JsonData = JsonData.Replace("\"", "'");
                JsonData = JsonData.Replace("\n\r", "");
                JsonData = JsonData.Replace("\r\n", "");
                JsonData = JsonData.Replace("\n", "");
                JsonData = JsonData.Replace("\r", "");

                string start = "'torrents':";
                JsonData = JsonData.Substring(JsonData.IndexOf("'torrents':") + start.Length);

                // Replace [ outside of quotes with #[#     
                Regex reg = new Regex("\\[(?=([^']*'[^']*')*(?![^']*'))");
                JsonData = reg.Replace(JsonData, "<<<");

                // Replace ] outside of quotes with #]#     
                reg = new Regex("\\](?=([^']*'[^']*')*(?![^']*'))");
                JsonData = reg.Replace(JsonData, ">>>");

                JsonData = JsonData.Replace("<<<<<<", "<<<");
                JsonData = JsonData.Replace("<<< <<<", "<<<");
                JsonData = JsonData.Substring(0, (JsonData.IndexOf(">>>>>>") + 3));
                JsonData = JsonData.Replace(">>>, <<<", ">>>\n\r<<<");
                JsonData = JsonData.Replace(">>>,<<<", ">>>\n\r<<<");
                
                // Create DataTable to hold list
                dt = new DataTable();
                dt.Columns.Add("key", typeof(string));
                dt.Columns.Add("status", typeof(Int64));
                dt.Columns.Add("FileName", typeof(string));
                dt.Columns.Add("Size", typeof(Int64));
                dt.Columns.Add("percentage", typeof(Int64));
                dt.Columns.Add("bytes", typeof(Int64));
                dt.Columns.Add("i5", typeof(Int64));
                dt.Columns.Add("ratio", typeof(Int64));   // 24 = 0.024
                dt.Columns.Add("UpSpeed", typeof(Int64));
                dt.Columns.Add("DownSpeed", typeof(Int64));
				dt.Columns.Add("ETA", typeof(Int64));
                dt.Columns.Add("s1", typeof(string));
                dt.Columns.Add("peers", typeof(int));
                dt.Columns.Add("peers2", typeof(int));
                dt.Columns.Add("seeds", typeof(int));
                dt.Columns.Add("seeds2", typeof(int));
                dt.Columns.Add("i14", typeof(Int64));
                dt.Columns.Add("i15", typeof(Int64));
                dt.Columns.Add("i16", typeof(Int64));

                // Regular Expression to parse data
                string pattern = @"<<<(?<row>.*)>>>";

                // Find data 
                MatchCollection mc = Regex.Matches(JsonData, pattern);

                // Create table row for each match
                foreach (Match m in mc)
                {
                    DataRow row = dt.NewRow();
                    string RowString = m.Groups["row"].Value;

                    // Replace commas used for columns with \b
                    //string commapat = ",(?=([^\\\"]*\\\"[^\\\"]*\\\")*(?![^\\\"]*\\\"))";

                    // Replace commas outside of single quotes with \b
                    string commapat = ",(?=([^']*'[^']*')*(?![^']*'))";

                    reg = new Regex(commapat);
                    RowString = reg.Replace(RowString, "\b");

                    // Remove "s
                    RowString = RowString.Replace("'", "");

                    dt.Rows.Add(RowString.Split('\b'));
                }
            }

            return dt;
        }


        /// <summary>
        /// Post call to uTorrent
        /// </summary>
        /// <param name="url"></param>
        /// <param name="login"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        private static string Call(string url, string login, string password)
        {
            string data = null;

            try
            {
                HttpWebRequest wr = WebRequest.Create(url) as HttpWebRequest;

                wr.Credentials = new NetworkCredential(login, password);

                using (WebResponse response = wr.GetResponse())
                {
                    StreamReader sr = new StreamReader(response.GetResponseStream());
                    data = sr.ReadToEnd();
                }                
            }
            catch
            {
                
            }
            return data;
        }
    }
}